/*
 * @Author: lineCode 1145938682@qq.com
 * @Date: 2024-12-22 14:10:21
 * @LastEditors: lineCode 1145938682@qq.com
 * @LastEditTime: 2025-08-28 22:39:08
 * @FilePath: /backend/shorthand-modules/shorthand-modules-content/src/main/java/com/angus/modules/content/repository/SysOrderRepository.java
 */
package com.angus.modules.content.repository;

import cn.hutool.core.text.CharSequenceUtil;
import com.angus.common.security.utils.SecurityUtils;
import com.angus.modules.content.domain.SysOrder;
import com.angus.modules.content.dto.QueryBaseDto;
import com.angus.modules.content.dto.SysFinanceDto;
import com.angus.modules.content.mapper.SysOrderMapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Repository;

import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;
import java.util.Map;


/**
 * @author lineCode
 */
@Repository
public class SysOrderRepository extends ServiceImpl<SysOrderMapper, SysOrder> {
    /**
     * 获取订单列表，确保LEFT JOIN在WHERE条件之前
     * 直接使用SQL查询避免顺序问题
     */
    public List<SysOrder> getOrderList(String orderNo, String courseCode, String courseName, Long userId, Integer payMethod, Integer status, Long recommendCode, String startTime, String endTime, Integer pageNum, Integer pageSize) {
        // 分页参数
        Integer page = (pageNum == null) ? Math.max(pageNum, 1) : 1;
        // 限制最大条数
        Integer limit = (pageSize == null) ? Math.max(1, Math.min(pageSize, 100)) : 10;
        // 计算偏移量
        Integer offset = (page - 1) * limit;
        return baseMapper.getOrderList(orderNo, courseCode, courseName, userId, payMethod,
                status, recommendCode, startTime, endTime, offset, limit);
    }

    public List<SysOrder> getPendingOrderList(String courseCode, Long userId) {
        LambdaQueryWrapper<SysOrder> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysOrder::getDelFlag, 0);
        queryWrapper.eq(SysOrder::getStatus,2);

        if (CharSequenceUtil.isNotBlank(courseCode)) {
            queryWrapper.eq(SysOrder::getCourseCode,courseCode);
        }
        if (userId != null && userId > 0){
            queryWrapper.eq(SysOrder::getUserId,userId);
        }

        LocalDateTime now = LocalDateTime.now();
        queryWrapper.gt(SysOrder::getExpireTime, now);

        queryWrapper.orderByAsc(SysOrder::getId);
        
        List<SysOrder> orderList = baseMapper.selectList(queryWrapper);
        return orderList != null ? orderList : Collections.emptyList();
    }


    public SysOrder getOrderByOrderNo(String orderNo,Long userId) {
        return baseMapper.selectOne(Wrappers.lambdaQuery(SysOrder.class)
                .eq(SysOrder::getUserId, userId)
                .eq(SysOrder::getOrderNo, orderNo)
                .eq(SysOrder::getDelFlag, 0));
    }

    public SysOrder getOrderByCourseCode(String courseCode,Long userId) {
        return baseMapper.selectOne(Wrappers.lambdaQuery(SysOrder.class)
                .eq(SysOrder::getUserId, userId)
                .eq(SysOrder::getCourseCode, courseCode)
                .eq(SysOrder::getStatus, 2)
                .eq(SysOrder::getDelFlag, 0));
    }

    public SysOrder getOrder(String orderNo) {
        return baseMapper.selectOne(Wrappers.lambdaQuery(SysOrder.class)
                .eq(SysOrder::getOrderNo, orderNo)
                .eq(SysOrder::getDelFlag, 0));
    }

    public void updateOrderStatus(String orderNo, Integer validDays) {
        LocalDateTime currentDateTime = LocalDateTime.now();
        baseMapper.update(null, Wrappers.lambdaUpdate(SysOrder.class)
                .eq(SysOrder::getOrderNo, orderNo)
                .set(SysOrder::getStatus, 2)
                .set(SysOrder::getPayTime, currentDateTime)
                .set(SysOrder::getUpdateBy, SecurityUtils.getUsername())
                .set(SysOrder::getUpdateTime, currentDateTime)
                .set(SysOrder::getExpireTime, currentDateTime.plusDays(validDays))
                .eq(SysOrder::getDelFlag, 0));
    }

    public void updateOrderCancelStatus(String orderNo) {
        LocalDateTime currentDateTime = LocalDateTime.now();
        baseMapper.update(null, Wrappers.lambdaUpdate(SysOrder.class)
                .eq(SysOrder::getOrderNo, orderNo)
                .set(SysOrder::getStatus, 4)
                .set(SysOrder::getUpdateBy, SecurityUtils.getUsername())
                .set(SysOrder::getUpdateTime, currentDateTime)
                .eq(SysOrder::getDelFlag, 0));
    }

    public List<SysOrder> getPayFeesList(QueryBaseDto originalDto, SysFinanceDto financeDto) {
        // 分页参数
        Integer page = Math.max(originalDto.getPageNum(), 1);
        // 限制最大条数
        Integer limit = Math.max(1, Math.min(originalDto.getPageSize(), 100));
        // 计算偏移量
        Integer offset = (page - 1) * limit;
        return baseMapper.getPayFeesList(originalDto, financeDto, offset, limit);
    }

    public int countOrder(String orderNo, String courseCode, Integer status, Integer payMethod, String startTime, String endTime, Boolean isOrder) {
        LambdaQueryWrapper<SysOrder> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysOrder::getDelFlag, 0);
        if (!Boolean.TRUE.equals(isOrder)){
            queryWrapper.gt(SysOrder::getStatus, 1);
        }
        if (CharSequenceUtil.isNotBlank(orderNo)) {
            queryWrapper.eq(SysOrder::getOrderNo, orderNo);
        }
        if (CharSequenceUtil.isNotBlank(courseCode)) {
            queryWrapper.eq(SysOrder::getCourseCode, courseCode);
        }
        if (status != null) {
            queryWrapper.eq(SysOrder::getStatus, status);
        }
        if (payMethod != null) {
            queryWrapper.eq(SysOrder::getPayMethod, payMethod);
        }
        if (CharSequenceUtil.isNotBlank(startTime)) {
            queryWrapper.ge(SysOrder::getCreateTime, startTime);
        }
        if (CharSequenceUtil.isNotBlank(endTime)) {
            queryWrapper.le(SysOrder::getCreateTime, endTime);
        }
        return Math.toIntExact(baseMapper.selectCount(queryWrapper));
    }

    /**
     * 订单收益
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @param courseName 课程名称
     * @return 订单收益
     */
    public List<Map<String, Object>> getPayFeesProfit(String startTime, String endTime, String courseName) {
        return baseMapper.getPayFeesProfitByTime(startTime, endTime, courseName);
    }

    /**
     * 删除订单
     * @param ids 订单ID列表
     * @return 是否删除成功
     */
    public boolean deleteByIds(List<Long> ids) {
        return baseMapper.deleteBatchIds(ids) > 0;
    }
}